#!/usr/bin/env python
# encoding: utf-8
'''
@author: luohui
@license: (C) Copyright 2013-2018.
@contact: 254272115@qq.com
@software: personal
@file: baseoperate.py
@time: 2018/9/29 16:12
@desc:封装一些appium webdriver的基础操作方便调用
'''
from appium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import TimeoutException
from selenium.common.exceptions import NoSuchElementException
from config.sysconfig import *

import sys
import time


class BaseOperate(object):
    def __init__(self, remoteAddress, dc):
        self.driver = webdriver.Remote(command_executor='http://' + remoteAddress + '/wd/hub', desired_capabilities=dc)

    def find_element(self, *loc):
        """
        重封装的find方法，接受元祖类型的参数，默认等待元素5秒，寻找失败时自动截图
        :param loc:元组类型,必须是(By.NAME, 'username')这样的结构
        :return:元素对象webelement
        """
        try:
            webelement = WebDriverWait(self.driver, 5).until(lambda x: x.find_element(*loc))
            return webelement
        except (TimeoutException, NoSuchElementException) as e:
            # 寻找失败时自动截图至指定目录sreenshot，截图名称为调用方法名（测试用例名）+ 时间戳 + png后缀
            self.driver.get_screenshot_as_file(SCREENSHOTURL + sys._getframe(1).f_code.co_name + \
                                               time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))+".png")
            print('Error details :%s' % e.msg)

    def find_elements(self, *loc):
        """
        重封装的find方法，接受元祖类型的参数，默认等待元素5秒，寻找失败时自动截图
        :param loc:元组类型,必须是(By.NAME, 'username')这样的结构
        :return:元素对象webelement
        """
        try:
            webelements = WebDriverWait(self.driver, 5).until(lambda x: x.find_elements(*loc))
            return webelements
        except (TimeoutException, NoSuchElementException) as e:
            # 寻找失败时自动截图至指定目录sreenshot，截图名称为调用方法名（测试用例名）+ 时间戳 + png后缀
            self.driver.get_screenshot_as_file(SCREENSHOTURL + sys._getframe(1).f_code.co_name + \
                                               time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))+".png")
            print('Error details :%s' % e.msg)

    def click_element(self, *loc):
        """
        重封装的click方法，将寻找和点击封装到一起，适用于点击次数不多的元素
        :param loc:元组类型,必须是(By.NAME, 'username')这样的结构
        :return:None
        """
        try:
            webelement = self.find_element(*loc)
            webelement.click()
        except (TimeoutException, NoSuchElementException) as e:
            print('Error details :%s' % e.msg)

    def submit(self, * loc):
        """
        提交表单
        :param loc:元组类型,必须是(By.NAME, 'username')这样的结构
        :return:None
        """
        try:
            webelement = self.find_element(*loc)
            webelement.submit()
        except (TimeoutException, NoSuchElementException) as e:
            print('Error details :%s' % e.msg)

    def implicitly_wait(self, secs):
        """
        设置隐式等待时间，作用范围就是Webdriver对象实例的整个生命周期
        :return:等待时长
        """
        return self.driver.implicitly_wait(secs)

    def current_activity(self):
        """
        获取当前页面的activity名
        :return:当前页面的activity名
        """
        try:
            return self.driver.current_activity
        except (TimeoutException, NoSuchElementException) as e:
            print('Error details :%s' % e.msg)

    def clear_and_sendkeys(self, sendtexts, *loc):
        """
        先清除当前文本框内的文字再输入新的文字的方法
        :param sendtexts:要输入的新的文字
        :param loc:元组类型,必须是(By.NAME, 'username')这样的结构
        :return:None
        """
        try:
            webelement = self.find_element(*loc)
            webelement.clear()
            webelement.send_keys(sendtexts)
        except (TimeoutException, NoSuchElementException) as e:
            print('Error details :%s' % e.msg)

    def swipe(self, start_x, start_y, end_x, end_y, timeout=None):
        """
        从起点滑动到终点 A-B
        :param start_x: 起始位置的横坐标x
        :param start_y: 起始位置的纵坐标y
        :param end_x:   结束位置的横坐标x
        :param end_y:   结束位置的纵坐标y
        :param timeout: 持续时间
        :return:
        """
        try:
            self.driver.swipe(start_x, start_y, end_x, end_y, timeout)
        except (TimeoutException, NoSuchElementException) as e:
            print('Error details :%s' % e.msg)

    def scroll(self, *sloc, *eloc):
        """
        从A滚动到B
        :param sloc: 起始元素A,元组类型,必须是(By.NAME, 'username')这样的结构
        :param eloc: 结束元素B,元组类型,必须是(By.NAME, 'username')这样的结构
        :return:
        """
        try:
            start_ele = self.find_element(*sloc)
            end_ele = self.find_element(*eloc)
            self.driver.scroll(start_ele, end_ele)
        except (TimeoutException, NoSuchElementException) as e:
            print('Error details :%s' % e.msg)

    def key_event(self, key_code, meta_state=None):
        """
        发送按键
        简书按键地址:http://www.jianshu.com/p/71c3608de453
        :param key_code: 按键
        :param meta_state:
        :return:
        """
        self.driver.keyevent(key_code, meta_state)

    def get_contexts(self):
        """
        返回当前会话中的所有上下文，使用后可以识别H5页面的控件
        :return:
        """
        return self.driver.contexts

    def get_current_context(self):
        """
        返回当前窗口的上下文
        :return:
        """
        return self.driver.current_context

    def current_url(self):
        """
        获取当前h5的url
        :return:
        """
        return self.driver.current_url

    def current_window_handle(self):
        """
        返回当前的窗口句柄(handle)
        :return:
        """
        return self.driver.current_window_handle

    def get_screen_shot_as_file(self, filename):
        """
        截取当前窗口的截图保存
        :param filename: 错误截图的地址
        :return:
        """
        try:
            self.driver.get_screenshot_as_file(filename)
        except (TimeoutException, NoSuchElementException) as e:
            print('Error details :%s' % e.msg)

    def quit(self):
        """
        退出appium程序，并关闭App
        :return:
        """
        self.driver.quit()

